//
// Created by MaLei on 2022/10/27.
//

#include "peerconnection.h"
#include "third_party/abseil-cpp/absl/memory/memory.h"
#include "third_party/abseil-cpp/absl/types/optional.h"
#include "api/audio/audio_mixer.h"
#include "api/audio_codecs/audio_decoder_factory.h"
#include "api/audio_codecs/audio_encoder_factory.h"
#include "api/audio_codecs/builtin_audio_decoder_factory.h"
#include "api/audio_codecs/builtin_audio_encoder_factory.h"
#include "api/audio_options.h"
#include "api/create_peerconnection_factory.h"
#include "api/rtp_sender_interface.h"
#include "api/video_codecs/builtin_video_decoder_factory.h"
#include "api/video_codecs/builtin_video_encoder_factory.h"
#include "api/video_codecs/video_decoder_factory.h"
#include "api/video_codecs/video_encoder_factory.h"
#include "modules/audio_device/include/audio_device.h"
#include "modules/audio_processing/include/audio_processing.h"
#include "modules/video_capture/video_capture.h"
#include "modules/video_capture/video_capture_factory.h"
#include "p2p/base/port_allocator.h"
#include "pc/video_track_source.h"
#include "rtc_base/checks.h"
#include "rtc_base/logging.h"
#include "rtc_base/ref_counted_object.h"
#include "rtc_base/rtc_certificate_generator.h"
#include <iostream>

class DummySetSessionDescriptionObserver
        : public webrtc::SetSessionDescriptionObserver {
public:
    static DummySetSessionDescriptionObserver* Create() {
        return new rtc::RefCountedObject<DummySetSessionDescriptionObserver>();
    }
    virtual void OnSuccess() { RTC_LOG(INFO) << __FUNCTION__; }
    virtual void OnFailure(webrtc::RTCError error) {
        RTC_LOG(INFO) << __FUNCTION__ << " " << ToString(error.type()) << ": "
                      << error.message();
    }
};

void Peer::Pull(std::string url){

    peer_connection_factory_ = webrtc::CreatePeerConnectionFactory(
            nullptr /* network_thread */, nullptr /* worker_thread */,
            nullptr /* signaling_thread */, nullptr /* default_adm */,
            webrtc::CreateBuiltinAudioEncoderFactory(),
            webrtc::CreateBuiltinAudioDecoderFactory(),
            webrtc::CreateBuiltinVideoEncoderFactory(),
            webrtc::CreateBuiltinVideoDecoderFactory(), nullptr /* audio_mixer */,
            nullptr /* audio_processing */);

    if(!peer_connection_factory_)
    {
        RTC_LOG(LS_ERROR) << "create peer connection factory failed";
        return;
    }

    webrtc::PeerConnectionInterface::RTCConfiguration config;
    config.sdp_semantics = webrtc::SdpSemantics::kPlanB;
    config.enable_dtls_srtp = true;
//    webrtc::PeerConnectionInterface::IceServer server;
//    server.uri = GetPeerConnectionString();
//    config.servers.push_back(server);

    peer_connection_ = peer_connection_factory_->CreatePeerConnection(
            config, nullptr, nullptr, this);


    if(!peer_connection_)
    {
        RTC_LOG(LS_ERROR) << "create peer connection failed";
        return;
    }

    peer_connection_->CreateOffer(
            this, webrtc::PeerConnectionInterface::RTCOfferAnswerOptions());

}

void Peer::OnAddTrack(
        rtc::scoped_refptr<webrtc::RtpReceiverInterface> receiver,
        const std::vector<rtc::scoped_refptr<webrtc::MediaStreamInterface>>&
        streams) {
    RTC_LOG(INFO) << __FUNCTION__ << " [remote:] " << receiver->id();
}

void Peer::OnRemoveTrack(
        rtc::scoped_refptr<webrtc::RtpReceiverInterface> receiver) {
    RTC_LOG(INFO) << __FUNCTION__ << " [remote:] " << receiver->id();
}

void Peer::OnIceConnectionChange(
        webrtc::PeerConnectionInterface::IceConnectionState new_state) {
    RTC_LOG(INFO) << __FUNCTION__  << new_state;
}
void Peer::OnIceGatheringChange(
        webrtc::PeerConnectionInterface::IceGatheringState new_state) {
    RTC_LOG(INFO) << __FUNCTION__  << new_state;
}

void Peer::OnIceCandidate(const webrtc::IceCandidateInterface* candidate) {
    RTC_LOG(INFO) << __FUNCTION__ << " " << candidate->sdp_mline_index();
}

const char* csdp = "v=0\n"
                   "o=- 1010500135866541554 2 IN IP4 127.0.0.1\n"
                   "s=-\n"
                   "t=0 0\n"
                   "a=group:BUNDLE 0 1\n"
                   "a=extmap-allow-mixed\n"
                   "a=msid-semantic: WMS stream_id\n"
                   "m=audio 9 UDP/TLS/RTP/SAVPF 111 103 104 9 102 0 8 106 105 13 110 112 113 126\n"
                   "c=IN IP4 0.0.0.0\n"
                   "a=rtcp:9 IN IP4 0.0.0.0\n"
                   "a=ice-ufrag:8MHE\n"
                   "a=ice-pwd:9HF5okXb3QgCagoL1B/tVW8a\n"
                   "a=ice-options:trickle\n"
                   "a=fingerprint:sha-256 00:BD:26:90:54:E1:45:4F:32:C1:70:CE:3A:1A:33:AE:7F:63:18:FA:0F:49:B9:7B:4F:B4:F2:A0:AB:93:6B:F7\n"
                   "a=setup:actpass\n"
                   "a=mid:0\n"
                   "a=extmap:1 urn:ietf:params:rtp-hdrext:ssrc-audio-level\n"
                   "a=extmap:2 http://www.webrtc.org/experiments/rtp-hdrext/abs-send-time\n"
                   "a=extmap:3 http://www.ietf.org/id/draft-holmer-rmcat-transport-wide-cc-extensions-01\n"
                   "a=extmap:4 urn:ietf:params:rtp-hdrext:sdes:mid\n"
                   "a=extmap:5 urn:ietf:params:rtp-hdrext:sdes:rtp-stream-id\n"
                   "a=extmap:6 urn:ietf:params:rtp-hdrext:sdes:repaired-rtp-stream-id\n"
                   "a=sendrecv\n"
                   "a=msid:stream_id audio_label\n"
                   "a=rtcp-mux\n"
                   "a=rtpmap:111 opus/48000/2\n"
                   "a=rtcp-fb:111 transport-cc\n"
                   "a=fmtp:111 minptime=10;useinbandfec=1\n"
                   "a=rtpmap:103 ISAC/16000\n"
                   "a=rtpmap:104 ISAC/32000\n"
                   "a=rtpmap:9 G722/8000\n"
                   "a=rtpmap:102 ILBC/8000\n"
                   "a=rtpmap:0 PCMU/8000\n"
                   "a=rtpmap:8 PCMA/8000\n"
                   "a=rtpmap:106 CN/32000\n"
                   "a=rtpmap:105 CN/16000\n"
                   "a=rtpmap:13 CN/8000\n"
                   "a=rtpmap:110 telephone-event/48000\n"
                   "a=rtpmap:112 telephone-event/32000\n"
                   "a=rtpmap:113 telephone-event/16000\n"
                   "a=rtpmap:126 telephone-event/8000\n"
                   "a=ssrc:3268581619 cname:H4FeoAdgRURWSsSX\n"
                   "a=ssrc:3268581619 msid:stream_id audio_label\n"
                   "a=ssrc:3268581619 mslabel:stream_id\n"
                   "a=ssrc:3268581619 label:audio_label\n"
                   "m=video 9 UDP/TLS/RTP/SAVPF 96 97 98 99 100 101 127 120 125 119 124 107 108 109 35 36 123 118 122\n"
                   "c=IN IP4 0.0.0.0\n"
                   "a=rtcp:9 IN IP4 0.0.0.0\n"
                   "a=ice-ufrag:8MHE\n"
                   "a=ice-pwd:9HF5okXb3QgCagoL1B/tVW8a\n"
                   "a=ice-options:trickle\n"
                   "a=fingerprint:sha-256 00:BD:26:90:54:E1:45:4F:32:C1:70:CE:3A:1A:33:AE:7F:63:18:FA:0F:49:B9:7B:4F:B4:F2:A0:AB:93:6B:F7\n"
                   "a=setup:actpass\n"
                   "a=mid:1\n"
                   "a=extmap:14 urn:ietf:params:rtp-hdrext:toffset\n"
                   "a=extmap:2 http://www.webrtc.org/experiments/rtp-hdrext/abs-send-time\n"
                   "a=extmap:13 urn:3gpp:video-orientation\n"
                   "a=extmap:3 http://www.ietf.org/id/draft-holmer-rmcat-transport-wide-cc-extensions-01\n"
                   "a=extmap:12 http://www.webrtc.org/experiments/rtp-hdrext/playout-delay\n"
                   "a=extmap:11 http://www.webrtc.org/experiments/rtp-hdrext/video-content-type\n"
                   "a=extmap:7 http://www.webrtc.org/experiments/rtp-hdrext/video-timing\n"
                   "a=extmap:8 http://www.webrtc.org/experiments/rtp-hdrext/color-space\n"
                   "a=extmap:4 urn:ietf:params:rtp-hdrext:sdes:mid\n"
                   "a=extmap:5 urn:ietf:params:rtp-hdrext:sdes:rtp-stream-id\n"
                   "a=extmap:6 urn:ietf:params:rtp-hdrext:sdes:repaired-rtp-stream-id\n"
                   "a=sendrecv\n"
                   "a=msid:stream_id video_label\n"
                   "a=rtcp-mux\n"
                   "a=rtcp-rsize\n"
                   "a=rtpmap:96 VP8/90000\n"
                   "a=rtcp-fb:96 goog-remb\n"
                   "a=rtcp-fb:96 transport-cc\n"
                   "a=rtcp-fb:96 ccm fir\n"
                   "a=rtcp-fb:96 nack\n"
                   "a=rtcp-fb:96 nack pli\n"
                   "a=rtpmap:97 rtx/90000\n"
                   "a=fmtp:97 apt=96\n"
                   "a=rtpmap:98 VP9/90000\n"
                   "a=rtcp-fb:98 goog-remb\n"
                   "a=rtcp-fb:98 transport-cc\n"
                   "a=rtcp-fb:98 ccm fir\n"
                   "a=rtcp-fb:98 nack\n"
                   "a=rtcp-fb:98 nack pli\n"
                   "a=fmtp:98 profile-id=0\n"
                   "a=rtpmap:99 rtx/90000\n"
                   "a=fmtp:99 apt=98\n"
                   "a=rtpmap:100 VP9/90000\n"
                   "a=rtcp-fb:100 goog-remb\n"
                   "a=rtcp-fb:100 transport-cc\n"
                   "a=rtcp-fb:100 ccm fir\n"
                   "a=rtcp-fb:100 nack\n"
                   "a=rtcp-fb:100 nack pli\n"
                   "a=fmtp:100 profile-id=2\n"
                   "a=rtpmap:101 rtx/90000\n"
                   "a=fmtp:101 apt=100\n"
                   "a=rtpmap:127 H264/90000\n"
                   "a=rtcp-fb:127 goog-remb\n"
                   "a=rtcp-fb:127 transport-cc\n"
                   "a=rtcp-fb:127 ccm fir\n"
                   "a=rtcp-fb:127 nack\n"
                   "a=rtcp-fb:127 nack pli\n"
                   "a=fmtp:127 level-asymmetry-allowed=1;packetization-mode=1;profile-level-id=42001f\n"
                   "a=rtpmap:120 rtx/90000\n"
                   "a=fmtp:120 apt=127\n"
                   "a=rtpmap:125 H264/90000\n"
                   "a=rtcp-fb:125 goog-remb\n"
                   "a=rtcp-fb:125 transport-cc\n"
                   "a=rtcp-fb:125 ccm fir\n"
                   "a=rtcp-fb:125 nack\n"
                   "a=rtcp-fb:125 nack pli\n"
                   "a=fmtp:125 level-asymmetry-allowed=1;packetization-mode=0;profile-level-id=42001f\n"
                   "a=rtpmap:119 rtx/90000\n"
                   "a=fmtp:119 apt=125\n"
                   "a=rtpmap:124 H264/90000\n"
                   "a=rtcp-fb:124 goog-remb\n"
                   "a=rtcp-fb:124 transport-cc\n"
                   "a=rtcp-fb:124 ccm fir\n"
                   "a=rtcp-fb:124 nack\n"
                   "a=rtcp-fb:124 nack pli\n"
                   "a=fmtp:124 level-asymmetry-allowed=1;packetization-mode=1;profile-level-id=42e01f\n"
                   "a=rtpmap:107 rtx/90000\n"
                   "a=fmtp:107 apt=124\n"
                   "a=rtpmap:108 H264/90000\n"
                   "a=rtcp-fb:108 goog-remb\n"
                   "a=rtcp-fb:108 transport-cc\n"
                   "a=rtcp-fb:108 ccm fir\n"
                   "a=rtcp-fb:108 nack\n"
                   "a=rtcp-fb:108 nack pli\n"
                   "a=fmtp:108 level-asymmetry-allowed=1;packetization-mode=0;profile-level-id=42e01f\n"
                   "a=rtpmap:109 rtx/90000\n"
                   "a=fmtp:109 apt=108\n"
                   "a=rtpmap:35 AV1X/90000\n"
                   "a=rtcp-fb:35 goog-remb\n"
                   "a=rtcp-fb:35 transport-cc\n"
                   "a=rtcp-fb:35 ccm fir\n"
                   "a=rtcp-fb:35 nack\n"
                   "a=rtcp-fb:35 nack pli\n"
                   "a=rtpmap:36 rtx/90000\n"
                   "a=fmtp:36 apt=35\n"
                   "a=rtpmap:123 red/90000\n"
                   "a=rtpmap:118 rtx/90000\n"
                   "a=fmtp:118 apt=123\n"
                   "a=rtpmap:122 ulpfec/90000\n"
                   "a=ssrc-group:FID 3608967946 404514690\n"
                   "a=ssrc:3608967946 cname:H4FeoAdgRURWSsSX\n"
                   "a=ssrc:3608967946 msid:stream_id video_label\n"
                   "a=ssrc:3608967946 mslabel:stream_id\n"
                   "a=ssrc:3608967946 label:video_label\n"
                   "a=ssrc:404514690 cname:H4FeoAdgRURWSsSX\n"
                   "a=ssrc:404514690 msid:stream_id video_label\n"
                   "a=ssrc:404514690 mslabel:stream_id\n"
                   "a=ssrc:404514690 label:video_label\n"
                   "";
const char *rsdp = "v=0\n"
                  "o=- 0 0 IN IP4 127.0.0.1\n"
                  "s=webrtc_core\n"
                  "i=1.59.2\n"
                  "t=0 0\n"
                  "a=group:BUNDLE 0 1\n"
                  "a=msid-semantic: WMS 8_live\n"
                  "m=audio 1 UDP/TLS/RTP/SAVPF 111\n"
                  "c=IN IP4 0.0.0.0\n"
                  "a=rtcp:1 IN IP4 0.0.0.0\n"
                  "a=candidate:foundation 1 udp 100 121.51.91.237 8000 typ srflx raddr 121.51.91.237 rport 8000 generation 0\n"
                  "a=ice-ufrag:8_live_d46513502475512e\n"
                  "a=ice-pwd:b2407bec1b49993967ea5a8b\n"
                  "a=fingerprint:sha-256 8A:BD:A6:61:75:AF:31:4C:02:81:2A:FA:12:92:4C:48:7B:9F:23:DD:BF:3D:51:30:E7:59:5C:9B:17:3D:92:34\n"
                  "a=setup:passive\n"
                  "a=sendrecv\n"
                  "a=extmap:2 http://www.webrtc.org/experiments/rtp-hdrext/abs-send-time\n"
                  "a=extmap:3 http://www.ietf.org/id/draft-holmer-rmcat-transport-wide-cc-extensions-01\n"
                  "a=mid:0\n"
                  "a=rtcp-mux\n"
                  "a=rtpmap:111 opus/48000/2\n"
                  "a=rtcp-fb:111 nack\n"
                  "a=rtcp-fb:111 transport-cc\n"
                  "a=fmtp:111 minptime=10;useinbandfec=1\n"
                  "a=ssrc:316238560 cname:8_live\n"
                  "a=ssrc:316238560 msid:8_live live_audio\n"
                  "a=ssrc:316238560 mslabel:8_live\n"
                  "a=ssrc:316238560 label:live_audio\n"
                  "m=video 1 UDP/TLS/RTP/SAVPF 108 124 125 127\n"
                  "c=IN IP4 0.0.0.0\n"
                  "a=rtcp:1 IN IP4 0.0.0.0\n"
                  "a=candidate:foundation 1 udp 100 121.51.91.237 8000 typ srflx raddr 121.51.91.237 rport 8000 generation 0\n"
                  "a=ice-ufrag:8_live_d46513502475512e\n"
                  "a=ice-pwd:b2407bec1b49993967ea5a8b\n"
                  "a=extmap:14 urn:ietf:params:rtp-hdrext:toffset\n"
                  "a=extmap:2 http://www.webrtc.org/experiments/rtp-hdrext/abs-send-time\n"
                  "a=extmap:13 urn:3gpp:video-orientation\n"
                  "a=extmap:3 http://www.ietf.org/id/draft-holmer-rmcat-transport-wide-cc-extensions-01\n"
                  "a=extmap:12 http://www.webrtc.org/experiments/rtp-hdrext/playout-delay\n"
                  "a=fingerprint:sha-256 8A:BD:A6:61:75:AF:31:4C:02:81:2A:FA:12:92:4C:48:7B:9F:23:DD:BF:3D:51:30:E7:59:5C:9B:17:3D:92:34\n"
                  "a=setup:passive\n"
                  "a=sendrecv\n"
                  "a=mid:1\n"
                  "a=rtcp-mux\n"
                  "a=rtcp-rsize\n"
                  "a=rtpmap:108 H264/90000\n"
                  "a=rtcp-fb:108 ccm fir\n"
                  "a=rtcp-fb:108 goog-remb\n"
                  "a=rtcp-fb:108 nack\n"
                  "a=rtcp-fb:108 nack pli\n"
                  "a=rtcp-fb:108 transport-cc\n"
                  "a=fmtp:108 level-asymmetry-allowed=1;packetization-mode=0;profile-level-id=42e01f\n"
                  "a=rtpmap:124 H264/90000\n"
                  "a=rtcp-fb:124 ccm fir\n"
                  "a=rtcp-fb:124 goog-remb\n"
                  "a=rtcp-fb:124 nack\n"
                  "a=rtcp-fb:124 nack pli\n"
                  "a=rtcp-fb:124 transport-cc\n"
                  "a=fmtp:124 level-asymmetry-allowed=1;packetization-mode=1;profile-level-id=42e01f\n"
                  "a=rtpmap:125 H264/90000\n"
                  "a=rtcp-fb:125 ccm fir\n"
                  "a=rtcp-fb:125 goog-remb\n"
                  "a=rtcp-fb:125 nack\n"
                  "a=rtcp-fb:125 nack pli\n"
                  "a=rtcp-fb:125 transport-cc\n"
                  "a=fmtp:125 level-asymmetry-allowed=1;packetization-mode=0;profile-level-id=42001f\n"
                  "a=rtpmap:127 H264/90000\n"
                  "a=rtcp-fb:127 ccm fir\n"
                  "a=rtcp-fb:127 goog-remb\n"
                  "a=rtcp-fb:127 nack\n"
                  "a=rtcp-fb:127 nack pli\n"
                  "a=rtcp-fb:127 transport-cc\n"
                  "a=fmtp:127 level-asymmetry-allowed=1;packetization-mode=1;profile-level-id=42001f\n"
                  "a=ssrc:299461344 cname:8_live\n"
                  "a=ssrc:299461344 msid:8_live live_video\n"
                  "a=ssrc:299461344 mslabel:8_live\n"
                  "a=ssrc:299461344 label:live_video";
void Peer::OnSuccess(webrtc::SessionDescriptionInterface* desc) {

    std::string sdp;
//    std::getline(std::cin, sdp);

    sdp = csdp;
    webrtc::SdpParseError error;
    auto mdesc =  webrtc::CreateSessionDescription("offer", sdp, &error);
    peer_connection_->SetLocalDescription(
            DummySetSessionDescriptionObserver::Create(), mdesc);

//    desc->ToString(&sdp);

//    RTC_LOG(LS_INFO) << "\n--------------local sdp--------------\n" << sdp << "\n\n\n";

    std::string remoteSdp;
    remoteSdp = rsdp;

//    RTC_LOG(LS_INFO) << "\n--------------remote sdp--------------\n" << sdp << "\n\n\n";

    // http request


    std::unique_ptr<webrtc::SessionDescriptionInterface> session_description;
    session_description.reset(webrtc::CreateSessionDescription("answer", remoteSdp, &error));
    if (!session_description) {
        RTC_LOG(WARNING) << "Can't parse received session description message. "
                            "SdpParseError was: "
                         << error.description;
        return;
    }
    peer_connection_->SetRemoteDescription(
            DummySetSessionDescriptionObserver::Create(),
            session_description.release());
}

void Peer::OnFailure(webrtc::RTCError error) {
    RTC_LOG(LERROR) << ToString(error.type()) << ": " << error.message();
}